// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameplayTagContainer.h"
#include "LyraVerbMessage.h"
#include "Net/Serialization/FastArraySerializer.h"

#include "LyraVerbMessageReplication.generated.h"

class UObject;
struct FLyraVerbMessageReplication;
struct FNetDeltaSerializeInfo;

/**
 * 表示一个动词消息的复制条目
 */
USTRUCT(BlueprintType)
struct FLyraVerbMessageReplicationEntry : public FFastArraySerializerItem
{
	GENERATED_BODY()

	// 默认构造函数
	FLyraVerbMessageReplicationEntry()
	{}

	// 使用消息初始化的构造函数
	FLyraVerbMessageReplicationEntry(const FLyraVerbMessage& InMessage)
		: Message(InMessage)
	{
	}

	// 获取调试字符串
	FString GetDebugString() const;

private:
	friend FLyraVerbMessageReplication;

	// 复制的动词消息
	UPROPERTY()
	FLyraVerbMessage Message;
};

/** 用于复制的动词消息容器 */
USTRUCT(BlueprintType)
struct FLyraVerbMessageReplication : public FFastArraySerializer
{
	GENERATED_BODY()

	// 默认构造函数
	FLyraVerbMessageReplication()
	{
	}

public:
	/**
	 * 设置所有者对象
	 * @param InOwner 所有者对象
	 */
	void SetOwner(UObject* InOwner) { Owner = InOwner; }

	// 从服务器向客户端广播消息
	void AddMessage(const FLyraVerbMessage& Message);

	//~FFastArraySerializer 合约
	/**
	 * 复制移除前的处理
	 * @param RemovedIndices 被移除的索引数组视图
	 * @param FinalSize 最终大小
	 */
	void PreReplicatedRemove(const TArrayView<int32> RemovedIndices, int32 FinalSize);
	/**
	 * 复制添加后的处理
	 * @param AddedIndices 被添加的索引数组视图
	 * @param FinalSize 最终大小
	 */
	void PostReplicatedAdd(const TArrayView<int32> AddedIndices, int32 FinalSize);
	/**
	 * 复制变更后的处理
	 * @param ChangedIndices 被变更的索引数组视图
	 * @param FinalSize 最终大小
	 */
	void PostReplicatedChange(const TArrayView<int32> ChangedIndices, int32 FinalSize);
	//~FFastArraySerializer 合约结束

	/**
	 * 网络增量序列化
	 * @param DeltaParms 增量序列化信息
	 * @return 序列化是否成功
	 */
	bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
	{
		return FFastArraySerializer::FastArrayDeltaSerialize<FLyraVerbMessageReplicationEntry, FLyraVerbMessageReplication>(CurrentMessages, DeltaParms, *this);
	}

private:
	/**
	 * 重新广播消息到消息子系统
	 * @param Message 要广播的消息
	 */
	void RebroadcastMessage(const FLyraVerbMessage& Message);

private:
	// 复制的游戏标签栈列表
	UPROPERTY()
	TArray<FLyraVerbMessageReplicationEntry> CurrentMessages;
	
	// 所有者（用于获取世界路径）
	UPROPERTY()
	TObjectPtr<UObject> Owner = nullptr;
};

// 为FLyraVerbMessageReplication启用网络增量序列化特性
template<>
struct TStructOpsTypeTraits<FLyraVerbMessageReplication> : public TStructOpsTypeTraitsBase2<FLyraVerbMessageReplication>
{
	enum
	{
		WithNetDeltaSerializer = true, // 启用网络增量序列化
	};
};